<template>
  <div class="custom-tree-container">
    <div class="block">
      <p>测试菜单</p>
      <el-tree
        ref="menuTree"
        :data="handledMenuData"
        :default-checked-keys="checkedKeys"
        show-checkbox
        node-key="id"
        default-expand-all
        :expand-on-click-node="false"
        @check="handleCheckedMenu"
      >
        <span
          :class="{ 'custom-tree-node': true, hidden: data.hidden }"
          slot-scope="{ node, data }"
        >
          <span>{{ node.label }}</span>
          <span v-if="data.actionList && data.actionList.length > 0">
            <el-checkbox
              v-model="checkedButtonsObj[button.actionCode]"
              v-for="(button, index) in data.actionList"
              :label="button.actionCode"
              :key="button.actionCode + index"
              @change="handleCheckedButtons($event, button.actionCode)"
              >{{ button.actionText }}</el-checkbox
            >
          </span>
          <span>
            <el-button type="text" size="mini" @click="() => append(data, 1)">
              添加菜单
            </el-button>
            <el-button
              v-if="data.id !== 'select_all'"
              type="text"
              size="mini"
              @click="() => append(data, 0)"
            >
              添加按钮
            </el-button>
          </span>
        </span>
      </el-tree>
      <!----添加菜单-->
      <el-dialog
        v-if="menuDialogVisible"
        :title="`添加${txt}`"
        :visible.sync="menuDialogVisible"
        width="30%"
      >
        <div>
          <el-form ref="form" :model="form" label-width="80px">
            <el-form-item :label="`${txt}名称`">
              <el-input v-model="form.name"></el-input>
            </el-form-item>
          </el-form>
        </div>
        <span slot="footer" class="dialog-footer">
          <el-button @click="menuDialogVisible = false">取 消</el-button>
          <el-button type="primary" @click="addMenu">确 定</el-button>
        </span>
      </el-dialog>
    </div>
  </div>
</template>
<script>
//
export default {
  name: 'AuthMenu',
  props: {
    // 权限菜单的初始数据
    initMenuData: {
      type: Array,
      required: true,
      default: () => []
    },
    // 被选中的按钮
    initCheckedButtons: {
      type: Array,
      default: () => []
    },
    // 被选中的菜单
    initCheckedMenus: {
      type: Array,
      default: () => []
    },
  },
  data() {
    return {
      handledMenuData: [],
      checkedButtonsObj: {
      },
      checkedButtonsArr: [],
      checkedMenus: [],
      checkedKeys: [],
      menuDialogVisible: false,
      form: {
        name: ''
      },
      type: 1 // 1是菜单 0是按钮
    }
  },
  computed: {
    txt() {
      return this.type == 1 ? '菜单' : '按钮'
    }
  },
  mounted() {
    this.handleMenu(this.initMenuData)
    this.$nextTick(() => {
      this.hideButtons()
      this.echoCheckedMenus()
    })
  },
  methods: {
    handleMenu(menuData) {
      // 初始化选中按钮
      this.echoCheckedButtons();
      console.log("menuData", menuData);
      if (menuData != null && menuData != [] && menuData.length > 0) {
        menuData.forEach(item => {
          if (!item.children) {
            item.children = []
          }
          if (item.children.length > 0) {
            this.handleMenu(item.children)
          }
          item.actionList && item.actionList.forEach(button => {
            const newButton = {
              id: button.actionCode,
              label: button.actionText,
              hidden: true,
            }
            this.$set(this.checkedButtonsObj, button.actionCode, this.checkedButtonsArr.includes(button.actionCode))
            item.children.push(newButton)

          })
        })
        this.handledMenuData = menuData
      }
      else {
        this.handledMenuData = [];
      }
    },
    // 回显被选中的菜单
    echoCheckedMenus() {
      this.initCheckedMenus.length > 0 && this.initCheckedMenus.forEach(item => {
        this.checkedKeys.push(item.id)
      })
      this.checkedKeys = this.checkedKeys.concat(this.checkedButtonsArr)
    },
    // 回显备选中的按钮
    echoCheckedButtons() {
      this.initCheckedButtons.length > 0 && this.initCheckedButtons.forEach(item => {
        this.checkedButtonsArr.push(item.actionCode)
      })
    },
    // 隐藏子集按钮
    hideButtons() {
      const hiddenButtons = this.$jquery('.hidden')
      const that = this
      hiddenButtons.each(function (i, item) {
        that.$jquery(item).parent().css('display', 'none')
      })
    },
    // 处理选中的菜单
    handleCheckedMenu(data, checkedNodes) {
      console.log('data===', data)
      console.log('checkedNodes===', checkedNodes)

      if (!checkedNodes.checkedKeys.includes(data.id)) {
        console.log('取消选中菜单')
        // 如果取消选中菜单且此菜单有按钮组，则取消所有按钮的选中状态,包括其子元素
        this.setCheckedButtons(data, false)

      } else {
        console.log('选中菜单')
        this.setCheckedButtons(data, true)
      }
      // 更新选中的菜单和按钮的值
      this.updateMenuAndButtons()
    }
    ,
    updateMenuAndButtons() {
      const nodes = this.$refs.menuTree.getCheckedNodes()
      // const halfNodes = this.$refs.menuTree.getHalfCheckedNodes()
      this.checkedButtonsArr = nodes.length > 0 && nodes.filter(item => item.hidden).map(item => ({
        "actionCode": item.id,
        "actionText": item.label
      })) || []

      this.checkedMenus = nodes.length > 0 && nodes.filter(item => !item.hidden) || []
      console.log('this.checkedButtonsArr', this.checkedButtonsArr)
      console.log('this.checkedMenus', this.checkedMenus)
      this.$emit('updateMenuAndButtons', {
        checkedButtonsArr: this.checkedButtonsArr,
        checkedMenus: this.checkedMenus
      })
    },
    setCheckedButtons(data, isChecked) {
      data.actionList && data.actionList.length > 0 && data.actionList.forEach(item => {
        this.checkedButtonsObj[item.actionCode] = isChecked
      })
      if (data.children && data.children.length > 0) {
        data.children.forEach(child => {
          this.setCheckedButtons(child, isChecked)
        })
      }
    },
    // 处理选中的按钮
    handleCheckedButtons(isChecked, buttonCode) {
      // 如果选中了按钮，则自动设置其父级菜单为勾选状态，并将其添加至选中的按钮数组中保存起来
      if (isChecked) {
        this.checkedButtonsArr.push(buttonCode)
        this.$refs.menuTree.setChecked(buttonCode, true)
      } else {
        this.$refs.menuTree.setChecked(buttonCode, false)
      }
      this.updateMenuAndButtons()

    },

    append(data, type) {
      this.type = type
      this.menuDialogVisible = true
      this.form.name = ''
      this.menuData = data
    },
    addMenu() {
      const id = new Date().getTime()
      if (this.type === 1) {
        // 如果是添加菜单
        const newChild = { id, label: this.form.name, children: [] }
        if (!this.menuData.children) {
          this.$set(this.menuData, 'children', [])
        }
        this.menuData.children.push(newChild)
      } else {
        // 如果是添加按钮，需要添加子菜单，再添加按钮并将二者关联
        const newChild = { id, label: this.form.name, hidden: true }
        if (!this.menuData.children) {
          this.$set(this.menuData, 'children', [])
        }
        this.menuData.children.push(newChild)
        const button = { actionCode: id, actionText: this.form.name, }
        if (!this.menuData.actionList) {
          this.$set(this.menuData, 'actionList', [])
        }
        this.menuData.actionList.push(button)
        this.$set(this.checkedButtonsObj, id, false)
        this.$nextTick(() => {
          this.hideButtons()
        })
      }


      this.menuDialogVisible = false
    },

    // remove (node, data) {
    //   const parent = node.parent
    //   const children = parent.data.children || parent.data
    //   const index = children.findIndex(d => d.id === data.id)
    //   children.splice(index, 1)
    // }
  }
};
</script>

<style lang="scss" scoped>
.custom-tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  padding-right: 8px;
}
.custom-tree-container {
  ::v-deep .el-icon-caret-right {
    display: none;
  }
}
</style>
